aboutsummaryrefslogtreecommitdiff
path: root/src/routes/user/[user]/badges
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-10-06 01:41:44 -0700
committerFuwn <[email protected]>2024-10-06 01:41:44 -0700
commita84d9c9f47c7cd1b345d0283bef9f211a9727893 (patch)
tree554827840b67e8a0068e707fad973a8780f47957 /src/routes/user/[user]/badges
parentfeat(graphql): add subtitles (diff)
downloaddue.moe-a84d9c9f47c7cd1b345d0283bef9f211a9727893.tar.xz
due.moe-a84d9c9f47c7cd1b345d0283bef9f211a9727893.zip
feat(badges): move badge operations to graphql
Diffstat (limited to 'src/routes/user/[user]/badges')
-rw-r--r--src/routes/user/[user]/badges/+page.gql17
-rw-r--r--src/routes/user/[user]/badges/+page.server.ts5
-rw-r--r--src/routes/user/[user]/badges/+page.svelte853
-rw-r--r--src/routes/user/[user]/badges/+page.ts20
4 files changed, 495 insertions, 400 deletions
diff --git a/src/routes/user/[user]/badges/+page.gql b/src/routes/user/[user]/badges/+page.gql
new file mode 100644
index 00000000..44c35bd8
--- /dev/null
+++ b/src/routes/user/[user]/badges/+page.gql
@@ -0,0 +1,17 @@
+query UserBadges($id: Int!) {
+ User(id: $id) {
+ badges {
+ post
+ image
+ description
+ id
+ time
+ category
+ hidden
+ source
+ designer
+ shadow_hidden
+ click_count
+ }
+ }
+}
diff --git a/src/routes/user/[user]/badges/+page.server.ts b/src/routes/user/[user]/badges/+page.server.ts
deleted file mode 100644
index f18892a7..00000000
--- a/src/routes/user/[user]/badges/+page.server.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export const load = async ({ params }) => {
- return {
- username: params.user
- };
-};
diff --git a/src/routes/user/[user]/badges/+page.svelte b/src/routes/user/[user]/badges/+page.svelte
index 499233ce..c4d48454 100644
--- a/src/routes/user/[user]/badges/+page.svelte
+++ b/src/routes/user/[user]/badges/+page.svelte
@@ -3,7 +3,6 @@
import { userIdentity } from '$lib/Data/AniList/identity';
import { user, type User } from '$lib/Data/AniList/user';
import type { Badge } from '$lib/Database/SB/User/badges';
- // import { domToBlob } from 'modern-screenshot';
import { onDestroy, onMount } from 'svelte';
import HeadTitle from '$lib/Home/HeadTitle.svelte';
import { databaseTimeToDate, dateToInputTime, inputTimeToDatabaseTime } from '$lib/Utility/time';
@@ -20,16 +19,118 @@
import { page } from '$app/stores';
import type { UserPreferences } from '$lib/Database/SB/User/preferences';
import { browser } from '$app/environment';
- // import { io } from 'socket.io-client';
import BadgePreview from '$lib/User/BadgeWall/BadgePreview.svelte';
import authorisedJson from '$lib/Data/Static/authorised.json';
import identity from '$stores/identity';
import '$lib/User/BadgeWall/badges.css';
import Badges from '$lib/User/BadgeWall/Badges.svelte';
import type { IndexedBadge } from '$lib/User/BadgeWall/badge';
+ import { graphql } from '$houdini';
export let data;
+ $: ({ UserBadges } = data);
+
+ const updateBadgeQuery = graphql(`
+ mutation UpdateBadge(
+ $id: Int
+ $post: String
+ $image: String
+ $description: String
+ $time: String
+ $category: String
+ $hidden: Boolean
+ $source: String
+ $designer: String
+ ) {
+ updateBadge(
+ id: $id
+ post: $post
+ image: $image
+ description: $description
+ time: $time
+ category: $category
+ hidden: $hidden
+ source: $source
+ designer: $designer
+ ) {
+ post
+ image
+ description
+ id
+ time
+ category
+ hidden
+ source
+ designer
+ shadow_hidden
+ click_count
+ }
+ }
+ `);
+
+ const pruneBadgesQuery = graphql(`
+ mutation PruneUserBadges {
+ pruneUserBadges {
+ post
+ image
+ description
+ id
+ time
+ category
+ hidden
+ source
+ designer
+ shadow_hidden
+ click_count
+ }
+ }
+ `);
+
+ const hideCategoryQuery = graphql(`
+ mutation HideCategory($category: String) {
+ hideBadge(category: $category) {
+ post
+ image
+ description
+ id
+ time
+ category
+ hidden
+ source
+ designer
+ shadow_hidden
+ click_count
+ }
+ }
+ `);
+
+ const deleteBadgeQuery = graphql(`
+ mutation DeleteBadge($id: Int!) {
+ deleteBadge(id: $id) {
+ post
+ image
+ description
+ id
+ time
+ category
+ hidden
+ source
+ designer
+ shadow_hidden
+ click_count
+ }
+ }
+ `);
+
+ const shadowHideBadgeQuery = graphql(`
+ mutation ShadowHideBadge($id: Int!, $state: Boolean) {
+ shadowHideBadge(id: $id, state: $state) {
+ id
+ }
+ }
+ `);
+
interface ImportImage {
link?: string;
image: string;
@@ -40,7 +141,6 @@
let currentUserIdentity: ReturnType<typeof userIdentity>;
let error: null | string;
// const socket = io();
- let badgesPromise: Promise<Response>;
let awcPromise: Promise<Response>;
// let dark = true;
// let transparent = false;
@@ -67,16 +167,12 @@
type GroupedBadges = { [key: string]: IndexedBadge[] };
- const getBadges = () => (badgesPromise = fetch(root(`/api/badges?id=${badger.id}`)));
-
const setShadowHide = () =>
- fetch(`/api/badges?shadowHide=${badger.id}`, {
- method: 'PUT'
- }).then(getBadges);
+ shadowHideBadgeQuery.mutate({
+ id: badger.id as number
+ });
onMount(async () => {
- // socket.on('badges', (message) => (badges = message));
-
if (browser && localStorage.getItem('badgeWallNoticeDismissed')) noticeDismissed = true;
badger = isId
@@ -92,7 +188,6 @@
return;
}
- badgesPromise = fetch(root(`/api/badges?id=${badger.id}`));
awcPromise = fetch(proxy(`https://awc.moe/challenger/${badger.name}`));
preferences = await (await fetch(root(`/api/preferences?id=${badger.id}`))).json();
@@ -118,8 +213,6 @@
if (data.user && !isId) {
currentUserIdentity = userIdentity(data.user);
-
- // socket.emit('badges', data.user);
} else {
currentUserIdentity = new Promise((resolve) =>
resolve({
@@ -181,32 +274,27 @@
return;
}
- badgesPromise = fetch(
- `/api/badges?image=${encodeURIComponent(imageURL.value)}&post=${encodeURIComponent(
- activityURL.value || '#'
- )}${
- description.value.length > 0 ? `&description=${encodeURIComponent(description.value)}` : ''
- }${category.value.length > 0 ? `&category=${encodeURIComponent(category.value)}` : ''}${
- time.valueAsDate
- ? `&time=${encodeURIComponent(inputTimeToDatabaseTime(time.valueAsDate))}`
- : ''
- }${
- selectedBadge && selectedBadge.id ? `&update=${encodeURIComponent(selectedBadge.id)}` : ''
- }&hidden=${hidden.value === 'Hidden'}${
- source.value.length > 0 ? `&source=${encodeURIComponent(source.value)}` : ''
- }${designer.value.length > 0 ? `&designer=${encodeURIComponent(designer.value)}` : ''}`,
- {
- method: 'PUT'
- }
- );
-
- error = null;
- imageURL.value = '';
- activityURL.value = '';
- description.value = '';
- category.value = '';
- hidden.value = 'Shown';
- selectedBadge = undefined;
+ updateBadgeQuery
+ .mutate({
+ id: selectedBadge?.id,
+ image: imageURL.value,
+ post: activityURL.value || '#',
+ description: description.value,
+ category: category.value,
+ time: time.valueAsDate ? inputTimeToDatabaseTime(time.valueAsDate) : undefined,
+ hidden: hidden.value === 'Hidden',
+ source: source.value,
+ designer: designer.value
+ })
+ .then(() => {
+ error = null;
+ imageURL.value = '';
+ activityURL.value = '';
+ description.value = '';
+ category.value = '';
+ hidden.value = 'Shown';
+ selectedBadge = undefined;
+ });
};
const removeAllBadges = () => {
@@ -223,9 +311,8 @@
}
selectedBadge = undefined;
- badgesPromise = fetch(root(`/api/badges?prune=true`), {
- method: 'DELETE'
- });
+
+ pruneBadgesQuery.mutate(null).then();
};
const removeBadge = (badge: Badge) => {
@@ -245,9 +332,12 @@
(document.querySelector(`#badge-${badge.id}`) as HTMLAnchorElement).style.display = 'none';
selectedBadge = undefined;
- badgesPromise = fetch(root(`/api/badges?id=${badge.id}`), {
- method: 'DELETE'
- });
+
+ deleteBadgeQuery
+ .mutate({
+ id: badge.id
+ })
+ .then();
};
const groupBadges = (badges: IndexedBadge[]) => {
@@ -369,7 +459,7 @@
});
const migrateCategory = () => {
- badgesPromise = fetch(
+ fetch(
`/api/badges?migrate=true&original=${encodeURIComponent(
(document.querySelector('#migrate_original') as HTMLInputElement).value
)}&new=${encodeURIComponent(
@@ -378,22 +468,15 @@
{
method: 'PUT'
}
- );
-
- migrateMode = false;
+ ).then(() => (migrateMode = false));
};
const hideCategory = () => {
- badgesPromise = fetch(
- `/api/badges?hide=true&category=${encodeURIComponent(
- (document.querySelector('#category_hide') as HTMLInputElement).value
- )}`,
- {
- method: 'PUT'
- }
- );
-
- hideMode = false;
+ hideCategoryQuery
+ .mutate({
+ category: (document.querySelector('#category_hide') as HTMLInputElement).value
+ })
+ .then(() => (hideMode = false));
};
// const exportBadges = (groupedBadges: [string, Badge[]][]) => {
@@ -455,12 +538,12 @@
const shadowHideBadge = () => {
if (!selectedBadge && !authorised) return;
- badgesPromise = fetch(
- `/api/badges?shadowHideBadge=${selectedBadge?.id}&status=${selectedBadge?.shadow_hidden}&id=${badger.id}`,
- {
- method: 'PUT'
- }
- );
+ shadowHideBadgeQuery
+ .mutate({
+ id: badger.id as number,
+ state: selectedBadge?.shadow_hidden as boolean
+ })
+ .then();
};
</script>
@@ -478,376 +561,356 @@
{:then identity}
{@const isOwner = identity && (isId ? identity.id : identity.name) === data.username}
- {#await badgesPromise}
+ {#if $UserBadges.fetching || !$UserBadges.data}
<Message message="Loading badges ..." />
<Skeleton grid={true} count={100} width="150px" height="170px" />
- {:then badgesResponse}
- {#if badgesResponse}
- {#await badgesResponse.clone().json()}
- <Message message="Parsing badges ..." />
-
- <Skeleton grid={true} count={100} width="150px" height="170px" />
- {:then ungroupedBadgesAny}
- {@const ungroupedBadges = castBadgesToIndexedBadges(ungroupedBadgesAny)}
- {@const isBadgeSelected =
- selectedBadge &&
- selectedBadge !== undefined &&
- selectedBadge.image &&
- selectedBadge.image !== undefined &&
- !editMode}
-
- <div id="badges">
- {#if preferences && !preferences.hide_awc_badges}
- <AWC {awcPromise} {categoryFilter} {isOwner} {preferences} />
+ {:else}
+ {@const ungroupedBadges = castBadgesToIndexedBadges($UserBadges.data.User.badges)}
+ {@const isBadgeSelected =
+ selectedBadge &&
+ selectedBadge !== undefined &&
+ selectedBadge.image &&
+ selectedBadge.image !== undefined &&
+ !editMode}
+
+ <div id="badges">
+ {#if preferences && !preferences.hide_awc_badges}
+ <AWC {awcPromise} {categoryFilter} {isOwner} {preferences} />
+ {/if}
+
+ {#if ungroupedBadges === null}
+ <Message message="Loading badges ..." />
+
+ <Skeleton grid={true} count={10} width="150px" height="170px" />
+ {:else}
+ {@const groupedBadges = Object.entries(
+ groupBadges(removeHiddenBadges(isOwner, ungroupedBadges))
+ )}
+
+ {#if isOwner || authorised}
+ {@const shadowHiddenCount = ungroupedBadges.filter(
+ (badge) => badge.shadow_hidden
+ ).length}
+ {@const shadowHidden = shadowHiddenCount > 0}
+
+ {#if shadowHidden}
+ <div class="card">
+ <b>Notice:</b> The Badge Wall overseer system has detected badges containing
+ AI-generated material on your wall. {shadowHiddenCount} of your badges have been shadow
+ hidden.
+ <p />
+ You may use the "Un-shadow Hide Badges" button to unhide these badges, from where you
+ will be required to use the hide feature to hide these badges from the public, while
+ allowing them to stay visible to you as the account holder.
+ </div>
+ {:else if !noticeDismissed}
+ <div class="card">
+ <b>Notice:</b> AniList has begun purging outbound links which contain AI-generated
+ material, this includes Badge Wall. If you have collected badges with AI-generated
+ elements, kindly use the hide feature to hide these badges from the public, while
+ allowing them to stay visible to you as the account holder.
+ <p />
+ Failure to comply with this request at your earliest convenience will result in the hiding
+ of all badges from your Badge Wall.
+ <p />
+ <button
+ on:click={() => {
+ noticeDismissed = true;
+
+ localStorage.setItem('badgeWallNoticeDismissed', 'true');
+ }}
+ >
+ Dismiss
+ </button>
+ </div>
{/if}
- {#if ungroupedBadges === null}
- <Message message="Loading badges ..." />
+ <p />
- <Skeleton grid={true} count={10} width="150px" height="170px" />
- {:else}
- {@const groupedBadges = Object.entries(
- groupBadges(removeHiddenBadges(isOwner, ungroupedBadges))
- )}
+ <div class="card">
+ {#if authorised}
+ <button on:click={setShadowHide}>Shadow Hide Badges</button>
+ {/if}
- {#if isOwner || authorised}
- {@const shadowHiddenCount = ungroupedBadges.filter(
- (badge) => badge.shadow_hidden
- ).length}
- {@const shadowHidden = shadowHiddenCount > 0}
+ {#if isOwner && authorised}
+ <span style="margin: 0 0.625rem;">•</span>
+ {/if}
+
+ {#if isOwner}
+ <button
+ on:click={() => {
+ selectedBadge = undefined;
+ editMode = !editMode;
+ }}
+ >
+ {editMode
+ ? $locale().user.badges.editMode.disable
+ : $locale().user.badges.editMode.enable}
+ </button>
+ <span style="margin: 0 0.625rem;">•</span>
+ <button
+ on:click={() => {
+ selectedBadge = undefined;
+ importMode = !importMode;
+ }}
+ >
+ {importMode
+ ? $locale().user.badges.importMode.disable
+ : $locale().user.badges.importMode.enable}
+ </button>
+ <span style="margin: 0 0.625rem;">•</span>
+ <button
+ on:click={() => {
+ selectedBadge = undefined;
+ migrateMode = !migrateMode;
+ }}
+ >
+ Migrate Category
+ </button>
+ <span style="margin: 0 0.625rem;">•</span>
+ <button
+ on:click={() => {
+ selectedBadge = undefined;
+ hideMode = !hideMode;
+ }}
+ >
+ Hide Category
+ </button>
+ <!-- <!-- <span style="margin: 0 0.625rem;">•</span> -->
+ <!-- <button on:click={() => exportBadges(groupedBadges)}>Export Badges</button> -->
{#if shadowHidden}
- <div class="card">
- <b>Notice:</b> The Badge Wall overseer system has detected badges containing
- AI-generated material on your wall. {shadowHiddenCount} of your badges have been
- shadow hidden.
- <p />
- You may use the "Un-shadow Hide Badges" button to unhide these badges, from where
- you will be required to use the hide feature to hide these badges from the public,
- while allowing them to stay visible to you as the account holder.
- </div>
- {:else if !noticeDismissed}
- <div class="card">
- <b>Notice:</b> AniList has begun purging outbound links which contain
- AI-generated material, this includes Badge Wall. If you have collected badges
- with AI-generated elements, kindly use the hide feature to hide these badges
- from the public, while allowing them to stay visible to you as the account
- holder.
- <p />
- Failure to comply with this request at your earliest convenience will result in the
- hiding of all badges from your Badge Wall.
- <p />
- <button
- on:click={() => {
- noticeDismissed = true;
-
- localStorage.setItem('badgeWallNoticeDismissed', 'true');
- }}
- >
- Dismiss
- </button>
- </div>
+ <span style="margin: 0 0.625rem;">•</span>
+ <button on:click={setShadowHide}>Un-shadow Hide Badges</button>
{/if}
- <p />
-
- <div class="card">
- {#if authorised}
- <button on:click={setShadowHide}>Shadow Hide Badges</button>
- {/if}
-
- {#if isOwner && authorised}
- <span style="margin: 0 0.625rem;">•</span>
- {/if}
-
- {#if isOwner}
- <button
- on:click={() => {
- selectedBadge = undefined;
- editMode = !editMode;
- }}
- >
- {editMode
- ? $locale().user.badges.editMode.disable
- : $locale().user.badges.editMode.enable}
- </button>
- <span style="margin: 0 0.625rem;">•</span>
- <button
- on:click={() => {
- selectedBadge = undefined;
- importMode = !importMode;
- }}
- >
- {importMode
- ? $locale().user.badges.importMode.disable
- : $locale().user.badges.importMode.enable}
- </button>
- <span style="margin: 0 0.625rem;">•</span>
- <button
- on:click={() => {
- selectedBadge = undefined;
- migrateMode = !migrateMode;
- }}
- >
- Migrate Category
- </button>
- <span style="margin: 0 0.625rem;">•</span>
- <button
- on:click={() => {
- selectedBadge = undefined;
- hideMode = !hideMode;
- }}
- >
- Hide Category
- </button>
- <!-- <!-- <span style="margin: 0 0.625rem;">•</span> -->
- <!-- <button on:click={() => exportBadges(groupedBadges)}>Export Badges</button> -->
-
- {#if shadowHidden}
- <span style="margin: 0 0.625rem;">•</span>
- <button on:click={setShadowHide}>Un-shadow Hide Badges</button>
- {/if}
-
- {#if editMode && isOwner}
- {@const groups = groupedBadges
- .map((group) => group[0])
- .filter((group) => group !== 'Uncategorised')}
- {@const designers = castAsStringArray([
- ...new Set(
- ungroupedBadges
- .map((badge) => badge.designer)
- .filter((designer) => designer !== undefined && designer !== null)
- .filter(
- (designer, index, array) =>
- array.indexOf(designer) === index && !array.includes(`@${designer}`)
- )
+ {#if editMode && isOwner}
+ {@const groups = groupedBadges
+ .map((group) => group[0])
+ .filter((group) => group !== 'Uncategorised')}
+ {@const designers = castAsStringArray([
+ ...new Set(
+ ungroupedBadges
+ .map((badge) => badge.designer)
+ .filter((designer) => designer !== undefined && designer !== null)
+ .filter(
+ (designer, index, array) =>
+ array.indexOf(designer) === index && !array.includes(`@${designer}`)
)
- ])}
+ )
+ ])}
- <p />
+ <p />
- {#if error}
- <p style="color: red;">{error}</p>
- {/if}
+ {#if error}
+ <p style="color: red;">{error}</p>
+ {/if}
+ <input
+ type="text"
+ placeholder={$locale().user.badges.editMode.imageURL}
+ name="image_url"
+ minlength="1"
+ maxlength="1000"
+ size="15"
+ value={selectedBadge ? selectedBadge.image : ''}
+ />
+ <input
+ type="text"
+ placeholder={$locale().user.badges.editMode.activityURL}
+ name="activity_url"
+ minlength="1"
+ maxlength="1000"
+ size="15"
+ value={selectedBadge
+ ? selectedBadge.post === '#'
+ ? ''
+ : selectedBadge.post
+ : ''}
+ />
+ <input
+ type="text"
+ placeholder={$locale().user.badges.editMode.description}
+ name="description"
+ minlength="1"
+ maxlength="1000"
+ size="15"
+ value={selectedBadge ? selectedBadge.description : ''}
+ />
+ <Dropdown
+ items={groups.map((group) => ({
+ name: group,
+ url: '#',
+ onClick: () => {
+ const category = document.querySelector('input[name="category"]');
+
+ if (category instanceof HTMLInputElement) category.value = group;
+ }
+ }))}
+ header={false}
+ center={false}
+ >
+ <span slot="title">
<input
type="text"
- placeholder={$locale().user.badges.editMode.imageURL}
- name="image_url"
- minlength="1"
- maxlength="1000"
- size="15"
- value={selectedBadge ? selectedBadge.image : ''}
- />
- <input
- type="text"
- placeholder={$locale().user.badges.editMode.activityURL}
- name="activity_url"
+ placeholder={$locale().user.badges.editMode.category}
+ name="category"
minlength="1"
maxlength="1000"
size="15"
value={selectedBadge
- ? selectedBadge.post === '#'
+ ? selectedBadge.category === 'Uncategorised'
? ''
- : selectedBadge.post
+ : selectedBadge.category
: ''}
+ list="categories"
/>
- <input
- type="text"
- placeholder={$locale().user.badges.editMode.description}
- name="description"
- minlength="1"
- maxlength="1000"
- size="15"
- value={selectedBadge ? selectedBadge.description : ''}
- />
- <Dropdown
- items={groups.map((group) => ({
- name: group,
- url: '#',
- onClick: () => {
- const category = document.querySelector('input[name="category"]');
-
- if (category instanceof HTMLInputElement) category.value = group;
- }
- }))}
- header={false}
- center={false}
- >
- <span slot="title">
- <input
- type="text"
- placeholder={$locale().user.badges.editMode.category}
- name="category"
- minlength="1"
- maxlength="1000"
- size="15"
- value={selectedBadge
- ? selectedBadge.category === 'Uncategorised'
- ? ''
- : selectedBadge.category
- : ''}
- list="categories"
- />
- </span>
- </Dropdown>
- <span style="float: right;">
+ </span>
+ </Dropdown>
+ <span style="float: right;">
+ <input
+ type="datetime-local"
+ value={selectedBadge && selectedBadge.time
+ ? dateToInputTime(databaseTimeToDate(selectedBadge.time))
+ : ''}
+ />
+ <small>Must be full date and time, defaults to now if any fields empty</small>
+ </span>
+
+ <p />
+
+ <div class="edit-row-2">
+ <input
+ type="text"
+ placeholder={$locale().user.badges.editMode.source}
+ name="source"
+ minlength="1"
+ maxlength="1000"
+ size="16"
+ value={selectedBadge ? selectedBadge.source : ''}
+ />
+ <Dropdown
+ items={designers.map((designer) => ({
+ name: designer,
+ url: '#',
+ onClick: () => {
+ const designerField = document.querySelector('input[name="designer"]');
+
+ if (designerField instanceof HTMLInputElement)
+ designerField.value = designer;
+ }
+ }))}
+ header={false}
+ center={false}
+ >
+ <span slot="title">
<input
- type="datetime-local"
- value={selectedBadge && selectedBadge.time
- ? dateToInputTime(databaseTimeToDate(selectedBadge.time))
- : ''}
+ type="text"
+ placeholder={$locale().user.badges.editMode.designer}
+ name="designer"
+ minlength="1"
+ maxlength="1000"
+ size="17"
+ value={selectedBadge ? selectedBadge.designer : ''}
/>
- <small
- >Must be full date and time, defaults to now if any fields empty</small
- >
</span>
-
- <p />
-
- <div class="edit-row-2">
+ </Dropdown>
+ <Dropdown
+ items={[false, true].map((hidden) => ({
+ name: hidden ? 'Hidden' : 'Shown',
+ url: '#',
+ onClick: () => {
+ const hiddenInput = document.querySelector('input[name="hidden"]');
+
+ if (hiddenInput instanceof HTMLInputElement)
+ hiddenInput.value = hidden ? 'Hidden' : 'Shown';
+ }
+ }))}
+ header={false}
+ center={false}
+ >
+ <span slot="title">
<input
type="text"
- placeholder={$locale().user.badges.editMode.source}
- name="source"
+ placeholder="Shown"
+ name="hidden"
minlength="1"
maxlength="1000"
- size="16"
- value={selectedBadge ? selectedBadge.source : ''}
+ size="15"
+ value={selectedBadge
+ ? selectedBadge.hidden
+ ? 'Hidden'
+ : 'Shown'
+ : 'Shown'}
/>
- <Dropdown
- items={designers.map((designer) => ({
- name: designer,
- url: '#',
- onClick: () => {
- const designerField =
- document.querySelector('input[name="designer"]');
-
- if (designerField instanceof HTMLInputElement)
- designerField.value = designer;
- }
- }))}
- header={false}
- center={false}
- >
- <span slot="title">
- <input
- type="text"
- placeholder={$locale().user.badges.editMode.designer}
- name="designer"
- minlength="1"
- maxlength="1000"
- size="17"
- value={selectedBadge ? selectedBadge.designer : ''}
- />
- </span>
- </Dropdown>
- <Dropdown
- items={[false, true].map((hidden) => ({
- name: hidden ? 'Hidden' : 'Shown',
- url: '#',
- onClick: () => {
- const hiddenInput = document.querySelector('input[name="hidden"]');
-
- if (hiddenInput instanceof HTMLInputElement)
- hiddenInput.value = hidden ? 'Hidden' : 'Shown';
- }
- }))}
- header={false}
- center={false}
- >
- <span slot="title">
- <input
- type="text"
- placeholder="Shown"
- name="hidden"
- minlength="1"
- maxlength="1000"
- size="15"
- value={selectedBadge
- ? selectedBadge.hidden
- ? 'Hidden'
- : 'Shown'
- : 'Shown'}
- />
- </span>
- </Dropdown>
- <button class="button-lined" on:click={submitBadge}
- >{selectedBadge
- ? $locale().user.badges.editMode.update
- : $locale().user.badges.editMode.add}</button
- >
- {#if selectedBadge}
- {$locale().user.badges.editMode.or}
- <button
- class="button-lined"
- on:click={() => {
- if (selectedBadge) removeBadge(selectedBadge);
- }}>{$locale().user.badges.editMode.delete}</button
- >
- {/if}
- </div>
+ </span>
+ </Dropdown>
+ <button class="button-lined" on:click={submitBadge}
+ >{selectedBadge
+ ? $locale().user.badges.editMode.update
+ : $locale().user.badges.editMode.add}</button
+ >
+ {#if selectedBadge}
+ {$locale().user.badges.editMode.or}
+ <button
+ class="button-lined"
+ on:click={() => {
+ if (selectedBadge) removeBadge(selectedBadge);
+ }}>{$locale().user.badges.editMode.delete}</button
+ >
{/if}
- {/if}
- </div>
+ </div>
+ {/if}
{/if}
+ </div>
+ {/if}
- <p />
-
- <Badges
- {ungroupedBadges}
- {groupedBadges}
- {categoryFilter}
- {editMode}
- {preferences}
- bind:selectedBadge
- />
- {/if}
- </div>
-
- {#if isBadgeSelected}
- <!-- {@const anyAdjacentBadgeExists =
+ <p />
+
+ <Badges
+ {ungroupedBadges}
+ {groupedBadges}
+ {categoryFilter}
+ {editMode}
+ {preferences}
+ bind:selectedBadge
+ />
+ {/if}
+ </div>
+
+ {#if isBadgeSelected}
+ <!-- {@const anyAdjacentBadgeExists =
adjacentBadgeExists(selectedBadge, ungroupedBadges, -1) ||
adjacentBadgeExists(selectedBadge, ungroupedBadges, 1)} -->
- <Popup
- fullscreen
- show={isBadgeSelected}
- onLeave={() => {
- selectedBadge = undefined;
- }}
- >
- <BadgePreview
- bind:selectedBadge
- onNext={() => setAdjacentCursor(ungroupedBadges, 1)}
- onPrevious={() => setAdjacentCursor(ungroupedBadges, -1)}
- hasNext={adjacentBadgeExists(selectedBadge, ungroupedBadges, 1) !== undefined}
- hasPrevious={adjacentBadgeExists(selectedBadge, ungroupedBadges, -1) !== undefined}
- />
-
- {#if authorised}
- <button on:click={shadowHideBadge}>
- {#if selectedBadge && selectedBadge.shadow_hidden}
- Un-shadow
- {:else}
- Shadow
- {/if} Hide Badge ({selectedBadge ? selectedBadge.id : 0})
- </button>
- {/if}
- </Popup>
+ <Popup
+ fullscreen
+ show={isBadgeSelected}
+ onLeave={() => {
+ selectedBadge = undefined;
+ }}
+ >
+ <BadgePreview
+ bind:selectedBadge
+ onNext={() => setAdjacentCursor(ungroupedBadges, 1)}
+ onPrevious={() => setAdjacentCursor(ungroupedBadges, -1)}
+ hasNext={adjacentBadgeExists(selectedBadge, ungroupedBadges, 1) !== undefined}
+ hasPrevious={adjacentBadgeExists(selectedBadge, ungroupedBadges, -1) !== undefined}
+ />
+
+ {#if authorised}
+ <button on:click={shadowHideBadge}>
+ {#if selectedBadge && selectedBadge.shadow_hidden}
+ Un-shadow
+ {:else}
+ Shadow
+ {/if} Hide Badge ({selectedBadge ? selectedBadge.id : 0})
+ </button>
{/if}
- {:catch}
- <Popup fullscreen locked>Could not parse badges</Popup>
- {/await}
- {:else}
- <Message message="Loading badges ..." />
-
- <Skeleton grid={true} count={100} width="150px" height="170px" />
+ </Popup>
{/if}
- {:catch}
- <Popup fullscreen locked>Could not fetch badges</Popup>
- {/await}
+ {/if}
{:catch}
<AnimeRateLimited>This user's badges could not be loaded.</AnimeRateLimited>
{/await}
diff --git a/src/routes/user/[user]/badges/+page.ts b/src/routes/user/[user]/badges/+page.ts
new file mode 100644
index 00000000..8b7204ad
--- /dev/null
+++ b/src/routes/user/[user]/badges/+page.ts
@@ -0,0 +1,20 @@
+import { load_UserBadges } from '$houdini';
+import { user } from '$lib/Data/AniList/user';
+import type { LoadEvent } from '@sveltejs/kit';
+
+export const load = async (event: LoadEvent) => {
+ const username = event.params.user as string;
+ const userData = await user(username, /^\d+$/.test(username));
+
+ return {
+ ...(await load_UserBadges({
+ event,
+ variables: {
+ id: userData.id
+ }
+ })),
+ username,
+ userData,
+ event
+ };
+};